// Copyright Gary Evans 2006-2007.

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace Taumuon.Jabuka.MainApp
{
    /// <summary>
    /// Provides functionality to find all of the scenes present in the current assembly.
    /// </summary>
    public static class SceneFinder
    {

        /// <summary>
        /// Retrieves a list of scenes in the current assembly.
        /// </summary>
        /// <returns>A list of <see cref="SceneDescription"/>objects.</returns>
        public static List<SceneDescription> GetSceneDescriptions()
        {
            List<SceneDescription> sceneDescriptions = new List<SceneDescription>();

            Assembly assembly = Assembly.GetExecutingAssembly();
            Type[] types = assembly.GetTypes();
            foreach (Type type in types)
            {
                // Check whether the type supports the IScene interface.
                // and whether the type has a default constructor.
                if (type.IsClass
                    && type.GetConstructor(new Type[]{}) != null
                    && type.GetInterface(typeof(IScene).ToString()) != null)
                {
                    object[] attributes = type.GetCustomAttributes(typeof(SceneAttribute), false);

                    if (attributes != null && attributes.Length > 0)
                    {
                        SceneAttribute attribute = (SceneAttribute)attributes[0];

                        sceneDescriptions.Add(new SceneDescription(attribute.Title, attribute.Description,
                            type));
                    }
                }
            }

            return sceneDescriptions;
        }
    }

    /// <summary>
    /// The description of a Scene object, and the type that implements <see cref="IScene"/>.
    /// </summary>
    public class SceneDescription
    {
        #region Object Lifetime

        /// <summary>
        /// Construct a scene description.
        /// </summary>
        /// <param name="title">The title of the scene.</param>
        /// <param name="description">The description of the scene.</param>
        /// <param name="type">The type that implements the scene.</param>
        public SceneDescription(string title, string description, Type type)
        {
            this.title = title;
            this.description = description;
            this.type = type;
        }

        #endregion

        #region Properties

        /// <summary>
        /// The title of the scene.
        /// </summary>
        public string Title
        {
            get
            {
                return title;
            }
        }

        /// <summary>
        /// The description of the scene.
        /// </summary>
        public string Description
        {
            get
            {
                return description;
            }
        }

        /// <summary>
        /// The type that implements the scene.
        /// </summary>
        public Type Type
        {
            get
            {
                return type;
            }
        }

        #endregion Properties

        #region Overrides

        /// <summary>
        /// Override of ToString() displays the title for display in e.g. a ListBox.
        /// </summary>
        public override string ToString()
        {
            return this.title;
        }

        #endregion Overrides

        #region Member Variables

        private string title;
        private string description;
        private Type type;

        #endregion Member Variables
    }
}
